home *** CD-ROM | disk | FTP | other *** search
/ Practical Algorithms for Image Analysis / Practical Algorithms for Image Analysis.iso / CH_6.1 / SPP / SPP.C < prev    next >
C/C++ Source or Header  |  1999-09-11  |  6KB  |  279 lines

  1. /* 
  2.  * spp.c
  3.  * 
  4.  * Practical Algorithms for Image Analysis
  5.  * 
  6.  * Copyright (c) 1997, 1998, 1999 MLMSoftwareGroup, LLC
  7.  */
  8.  
  9. /*
  10.  * S(can) P(oint) P(attern)
  11.  *
  12.  */
  13.  
  14. #include <stdio.h>
  15. #include <stdlib.h>
  16. #include <string.h>
  17. #include <math.h>
  18. #include "spp.h"
  19.  
  20. #undef    DEBUG
  21. #undef    SHOW_PP
  22. #undef    DEBUG_SORT
  23.  
  24. #define    ON        1
  25. #define    OFF        0
  26.  
  27.  
  28. /* globals */
  29. unsigned char **image;          /* input/output image */
  30. int NMAX = 4000;                /* max no point objects in image */
  31.  
  32. int offset_of_y = OFFSETOF (struct Pix, y);
  33. int offset_of_x = OFFSETOF (struct Pix, x);
  34.  
  35. extern char *optarg;
  36. extern int optind, opterr;
  37.  
  38. int POINT_OBJ = ON;             /* default: assume pattern of point-objs */
  39. int SORT = OFF;
  40. int WRITE_FILE = OFF;
  41.  
  42.  
  43. /*
  44.  * comparison function for qsort():
  45.  * sort array of tuples in order of increassing y-values (not tested)
  46.  */
  47. int
  48. compare (t1, t2)
  49.      const void *t1, *t2;
  50. {
  51.   int i1, i2;
  52.  
  53.   i1 = *(int *) ((struct Pix *) t1 + offset_of_y);
  54.   i2 = *(int *) ((struct Pix *) t2 + offset_of_y);
  55.   return ((int) SIGN (i1 - i2));
  56. }
  57.  
  58.  
  59.  
  60. void
  61. fail_alloc (char *str, int code)
  62. {
  63.   printf ("\n...memory alloc for %s failed\n", str);
  64.   exit (code);
  65. }
  66.  
  67.  
  68. /*
  69.  * usage of routine
  70.  */
  71. void
  72. usage (char *progname)
  73. {
  74.   progname = last_bs (progname);
  75.   printf ("USAGE: %s inimg [-d] [-w file] [-L]\n", progname);
  76.   printf ("\n%s scans a point pattern in a given image\n", progname);
  77.   printf ("and generates data for later Vornoi analysis.\n\n");
  78.   printf ("ARGUMENTS:\n");
  79.   printf ("        inimg: input image filename (TIF)\n\n");
  80.   printf ("OPTIONS:\n");
  81.   printf ("     -d : default mode: scan pattern of point-like objects\n");
  82.   printf ("          marked in max_index-1 (254);\n");
  83.   printf ("          data are generated in order of increasing y-coordinates.\n");
  84.   printf (" -w file: write file (.vin) to disk\n");
  85.   printf ("     -L : print Software License for this module\n");
  86.   exit (1);
  87. }
  88.  
  89.  
  90.  
  91. void
  92. main (int argc, char *argv[])
  93. {
  94.   int i;
  95.   int nrows, ncols;
  96.  
  97.   struct Pix *Cxy;
  98.   long n_pts;
  99.   int status;
  100.   int xmin, ymin, xmax, ymax;
  101.   int jmin, imin, jmax, imax;
  102.   int left_x, right_x;
  103.  
  104.   char *buf;
  105.   int i_arg;
  106.   FILE *file;
  107.   Image *imgIO;                 /* structure for I/O images */
  108.   char in_filename[256];
  109.  
  110.  
  111. /* 
  112.  * cmd line options
  113.  */
  114.   static char *optstring = "dw:L";
  115.  
  116.  
  117.   in_filename[0] = '\0';
  118.  
  119. /*
  120.  * parse command line
  121.  */
  122.   optind = 2;
  123.   opterr = ON;                  /* give error messages */
  124.  
  125.   if (argc < 2)
  126.     usage (argv[0]);
  127.  
  128.   while ((i_arg = getopt (argc, argv, optstring)) != EOF) {
  129.     printf ("\n");
  130.     switch (i_arg) {
  131.     case 'd':
  132.       printf ("...option %c: default mode\n", i_arg);
  133.       POINT_OBJ = ON;
  134.       break;
  135.     case 'w':
  136.       printf ("...option %c: write file %s to disk\n",
  137.               i_arg, buf = optarg);
  138.  
  139.       if ((file = fopen (buf, "w")) == NULL) {
  140.         puts ("\n...could not open output file");
  141.         exit (1);
  142.       }
  143.       WRITE_FILE = ON;
  144.       break;
  145.     case 'L':
  146.       print_sos_lic ();
  147.       exit (0);
  148.     default:
  149.       printf ("...unknown condition encountered\n");
  150.       exit (1);
  151.       break;
  152.     }
  153.   }
  154.   strcpy (in_filename, argv[1]);
  155.  
  156. /*
  157.  * get the image
  158.  */
  159.   imgIO = ImageIn (in_filename);
  160.   if (imgIO->bps == 8 && imgIO->spp == 3) {
  161.     printf ("Got RGB image!!!\n");
  162.     fprintf (stderr, "Can only work with Grayscale or Binary TIFF files!!!\n");
  163.     exit (1);
  164.   }
  165.   image = imgIO->img;
  166.   nrows = imgIO->height;
  167.   ncols = imgIO->width;
  168.  
  169.   jmin = imin = 0;
  170.   jmax = ncols;
  171.   imax = nrows;
  172.  
  173.   left_x = jmin;
  174.   right_x = jmax - 1;
  175.   ncols = jmax - jmin;
  176.   nrows = imax - imin;
  177.  
  178. #ifdef DEBUG
  179.   printf ("\n...ncols = %d, nrows = %d\n", ncols, nrows);
  180. #endif
  181.  
  182.  
  183. /*
  184.  *  zero outer border of image
  185.  */
  186.   zero_border (imgIO, 1);
  187.  
  188.  
  189. /*
  190.  * memory allocation
  191.  */
  192.   if ((Cxy = (struct Pix *) calloc (NMAX, sizeof (struct Pix))) == NULL)
  193.       fail_alloc ("Cxy", 1);
  194.  
  195. /*
  196.  * extract coordinates of objects in point pattern
  197.  * -->note: data are extracted in order of increasing y!!
  198.  */
  199.   printf ("\n...extracting point object coordinates:");
  200.   n_pts = 0;
  201.   if ((status = x_pp (Cxy, &n_pts, left_x, imin, right_x, imax)) == 0) {
  202.     printf ("\n...no objects exceeds NMAX = %d\n", NMAX);
  203.     exit (1);
  204.   }
  205.   else
  206.     printf ("\n...found %ld points\n", n_pts);
  207.  
  208. /* realloc */
  209.  
  210. #ifdef SHOW_PP
  211.   printf ("\n...point coordinates:\n");
  212.   for (i = 0; i < n_pts; i++) {
  213.     printf ("... x[%d] = %4d, y[%d] = %4d\n",
  214.             i, (Cxy + i)->x, i, (Cxy + i)->y);
  215.   }
  216. #endif
  217.  
  218.  
  219.   if (SORT == OFF) {
  220.     printf ("\n...find extrema in (unsorted) data...\n");
  221.  
  222.     xmin = xmax = (Cxy + 0)->x;
  223.     ymin = ymax = (Cxy + 0)->y;
  224.     for (i = 1; i < n_pts; i++) {
  225.       if ((Cxy + i)->x < xmin)
  226.         xmin = (Cxy + i)->x;
  227.       if ((Cxy + i)->x > xmax)
  228.         xmax = (Cxy + i)->x;
  229.  
  230.       if ((Cxy + i)->y < ymin)
  231.         ymin = (Cxy + i)->y;
  232.       if ((Cxy + i)->y > ymax)
  233.         ymax = (Cxy + i)->y;
  234.     }
  235.     printf ("\n...xmin = %4d, ymin = %4d\n", xmin, ymin);
  236.     printf ("\n...xmax = %4d, ymax = %4d\n", xmax, ymax);
  237.   }
  238.  
  239. /*
  240.  * sort Cxy if required for later use
  241.  */
  242.   else if (SORT == ON) {
  243.     printf ("\n...sort data and find extrema...\n");
  244.  
  245.     qsort (Cxy, n_pts, sizeof (struct Pix), compare);
  246.  
  247.     xmin = xmax = (Cxy + 0)->x;
  248.     for (i = 1; i < n_pts; i++) {
  249.       if ((Cxy + i)->x < xmin)
  250.         xmin = (Cxy + i)->x;
  251.       if ((Cxy + i)->x > xmax)
  252.         xmax = (Cxy + i)->x;
  253.     }
  254.     ymin = (Cxy + 0)->y;
  255.     ymax = (Cxy + n_pts - 1)->y;
  256.  
  257. #ifdef DEBUG_SORT
  258.     printf ("\n...data after sorting:\n");
  259.     for (i = 0; i < n_pts; i++) {
  260.       printf ("... x[%d] = %4d, y[%d] = %4d\n",
  261.               i, (Cxy + i)->x, i, (Cxy + i)->y);
  262.     }
  263.     printf ("\n...xmin = %4d, ymin = %4d\n", xmin, ymin);
  264.     printf ("\n...xmax = %4d, ymax = %4d\n", xmax, ymax);
  265. #endif
  266.   }
  267.  
  268. /*
  269.  * write data file of format ( .vin) for use by Voronoi routines
  270.  */
  271.   if (WRITE_FILE == ON) {
  272.     write_vin_file (file, (int) n_pts, xmin, ymin, xmax, ymax, Cxy);
  273.     fclose (file);
  274.   }
  275.  
  276.   if (POINT_OBJ == ON)
  277.     free (Cxy);
  278. }
  279.